package com.ctshk.rpc.tour.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import com.ctshk.rpc.tour.req.es.TripCacheUpdateReq;
import com.ctshk.rpc.tour.service.ISeriesTripAppService;
import com.ctshk.rpc.tour.util.Utils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.service.support.BaseService;
import com.ctshk.common.utils.Assist;
import com.ctshk.rpc.tour.dto.TripIdDTO;
import com.ctshk.rpc.tour.entity.SeriesTrip;
import com.ctshk.rpc.tour.entity.SeriesTripInfoChangeRule;
import com.ctshk.rpc.tour.entity.SeriesTripInsurance;
import com.ctshk.rpc.tour.entity.SeriesTripTeamRule;
import com.ctshk.rpc.tour.entity.SeriesTripTouristType;
import com.ctshk.rpc.tour.entity.SeriesTripVisa;
import com.ctshk.rpc.tour.mapper.SeriesTripInsuranceMapper;
import com.ctshk.rpc.tour.mapper.SeriesTripMapper;
import com.ctshk.rpc.tour.mapper.SeriesTripTeamRuleMapper;
import com.ctshk.rpc.tour.mapper.SeriesTripVisaMapper;
import com.ctshk.rpc.tour.req.Passenger;
import com.ctshk.rpc.tour.req.SeriesTripInfoChangeRuleReq;
import com.ctshk.rpc.tour.req.SeriesTripReq;
import com.ctshk.rpc.tour.req.SeriesTripTeamRuleReq;
import com.ctshk.rpc.tour.req.TripBasicInformationReq;
import com.ctshk.rpc.tour.req.trip.TripInsuranceReq;
import com.ctshk.rpc.tour.req.trip.TripVisaReq;
import com.ctshk.rpc.tour.service.ISeriesTripTeamRuleService;

import ma.glasnost.orika.MapperFactory;
import org.springframework.util.StringUtils;

/**
 * <p>
 * 行程团队规则 服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-01-12
 */
@DubboService
public class SeriesTripTeamRuleServiceImpl extends ServiceImpl<SeriesTripTeamRuleMapper, SeriesTripTeamRule> implements ISeriesTripTeamRuleService, BaseService {

    /**
     * 行程服务
     */
    @Autowired
    private SeriesTripMapper seriesTripMapper;

    /**
     * 旅客类型
     */
    @Autowired
    private SeriesTripTouristTypeServiceImpl seriesTripTouristTypeService;

    @Autowired
    private SeriesTripInfoChangeRuleServiceImpl seriesTripInfoChangeRuleService;

    /**
     * 签证服务
     */
    @Autowired
    private SeriesTripVisaMapper seriesTripVisaMapper;


    /**
     * 保险服务
     */
    @Autowired
    private SeriesTripInsuranceMapper seriesTripInsuranceMapper;

    /**
     * 数据转换
     */
    @Autowired
    private MapperFactory mapperFactory;

    @Autowired
    private ISeriesTripAppService iSeriesTripAppService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public TripIdDTO basicInformation(TripBasicInformationReq tripBasicInformationReq, Long userId) {
        if (tripBasicInformationReq.getBusinessType() == null){
            tripBasicInformationReq.setBusinessType(1);
        }
        SeriesTripTeamRuleReq seriesTripTeamRuleReq = tripBasicInformationReq.getSeriesTripTeamRuleReq();
        Long id = tripBasicInformationReq.getId();
        TripIdDTO tripIdDTO = new TripIdDTO();
        if (id == null) {
            //新增行程基本资料
            SeriesTripReq seriesTripReq = tripBasicInformationReq.getSeriesTripReq();
            
            //验证行程码是否已存在
            if (Assist.isNotBlank(seriesTripReq.getTripCode())) {
            	if (Assist.isNotEmpty(seriesTripMapper.selectListByKey("trip_code", seriesTripReq.getTripCode()))) {
            		throw new BusinessException(SystemError.TOUR_ORDER_30008);
            	}
            }
            
            SeriesTrip seriesTrip = newCreateEntityUserId(SeriesTrip.class, null, userId);
            BeanUtils.copyProperties(seriesTripReq, seriesTrip);
            seriesTrip.setCreateId(userId);
            seriesTrip.setGmtCreate(LocalDateTime.now());
            seriesTrip.setIsDeleted(0);
            seriesTrip.setCurrentStep(1);

            //负责人
            seriesTrip.setChargePersonId(seriesTripTeamRuleReq.getChargePersonId());
            seriesTrip.setChargePersonName(seriesTripTeamRuleReq.getChargePersonName());
            seriesTrip.setChargePersonNumber(seriesTripTeamRuleReq.getChargePersonNumber());
            //操作人

            seriesTrip.setOpId(seriesTripTeamRuleReq.getOpId());
            seriesTrip.setOpName(seriesTripTeamRuleReq.getOpName());
            seriesTrip.setOpName(seriesTripTeamRuleReq.getOpNumber());
            seriesTripMapper.insert(seriesTrip);
            Long tripId = seriesTrip.getId();
            List<TripVisaReq> visaReqList = seriesTripReq.getTripVisaList();
            if (CollectionUtils.isNotEmpty(visaReqList)) {
                List<SeriesTripVisa> seriesTripVisaList = new ArrayList<>();
                for (TripVisaReq tripVisaReq : visaReqList) {
                    SeriesTripVisa seriesTripVisa = newCreateEntityUserId(SeriesTripVisa.class, null, userId);
                    seriesTripVisa.setVisaId(tripVisaReq.getVisaId());
                    seriesTripVisa.setName(tripVisaReq.getName());
                    seriesTripVisa.setTripId(tripId);
                    seriesTripVisaList.add(seriesTripVisa);
                }
                seriesTripVisaMapper.insertBatchSomeColumn(seriesTripVisaList);
            }
            List<TripInsuranceReq> insuranceReqList =seriesTripReq.getInsuranceList();
            if (CollectionUtils.isNotEmpty(insuranceReqList)){
                List<SeriesTripInsurance> seriesTripInsuranceList =new ArrayList<>();
                for (TripInsuranceReq tripInsuranceReq : insuranceReqList) {
                    SeriesTripInsurance seriesTripInsurance = newCreateEntityUserId(SeriesTripInsurance.class, null, userId);
                    seriesTripInsurance.setName(tripInsuranceReq.getName());
                    seriesTripInsurance.setTripId(tripId);
                    seriesTripInsurance.setInsuranceId(tripInsuranceReq.getInsuranceId());
                    seriesTripInsuranceList.add(seriesTripInsurance);
                }
                seriesTripInsuranceMapper.insertBatchSomeColumn(seriesTripInsuranceList);
            }


            List<Passenger> passengerList = seriesTripTeamRuleReq.getPassenger();

            //新增团队规则数据
            SeriesTripTeamRule seriesTripTeamRule = new SeriesTripTeamRule();
            BeanUtils.copyProperties(seriesTripTeamRuleReq, seriesTripTeamRule);
            seriesTripTeamRule.setTripId(tripId);

            baseMapper.insert(seriesTripTeamRule);
            Long ruleId = seriesTripTeamRule.getId();
            if (CollectionUtils.isNotEmpty(passengerList)) {
                List<SeriesTripTouristType> tripTouristTypeList = new ArrayList();
                SeriesTripTouristType seriesTripTouristType = null;

                for (Passenger passenger : passengerList) {
                    //TODO 添加sort
                    seriesTripTouristType = newCreateEntityUserId(SeriesTripTouristType.class, null, userId);
                    seriesTripTouristType.setId(IdWorker.getId());
                    seriesTripTouristType.setTripId(tripId);
                    seriesTripTouristType.setRuleId(ruleId);
                    seriesTripTouristType.setMainDataId(passenger.getId());
                    seriesTripTouristType.setAgeBegin(passenger.getAgeBegin());
                    seriesTripTouristType.setAgeEnd(passenger.getAgeEnd());
                    seriesTripTouristType.setName(passenger.getName());
                    seriesTripTouristType.setSort(passenger.getSort());
                    seriesTripTouristType.setIsOccupyBed(passenger.getIsOccupyBed());
                    tripTouristTypeList.add(seriesTripTouristType);
                }
                seriesTripTouristTypeService.saveBatch(tripTouristTypeList);
            }
            List<SeriesTripInfoChangeRuleReq> ruleList = seriesTripTeamRuleReq.getChangeRuleList();
            if (CollectionUtils.isNotEmpty(ruleList)) {
                List<SeriesTripInfoChangeRule> seriesTripInfoChangeRuleList = new ArrayList<>();
                SeriesTripInfoChangeRule seriesTripInfoChangeRule = null;
                for (SeriesTripInfoChangeRuleReq seriesTripInfoChangeRuleReq : ruleList) {
                    seriesTripInfoChangeRule = newCreateEntityUserId(SeriesTripInfoChangeRule.class, null, userId);
                    seriesTripInfoChangeRule.setTripId(tripId);
                    seriesTripInfoChangeRule.setGroupRuleId(ruleId);
                    seriesTripInfoChangeRule.setMainDataId(seriesTripInfoChangeRuleReq.getMainDataId());
                    seriesTripInfoChangeRule.setName(seriesTripInfoChangeRuleReq.getName());
                    seriesTripInfoChangeRuleList.add(seriesTripInfoChangeRule);
                }
                seriesTripInfoChangeRuleService.saveBatch(seriesTripInfoChangeRuleList);
            }
            tripIdDTO.setId(seriesTrip.getId());
        }
        if (id != null) {
            //修改行程基本资料
            SeriesTripReq seriesTripReq =tripBasicInformationReq.getSeriesTripReq();
            SeriesTrip seriesTrip =new SeriesTrip();
            BeanUtils.copyProperties(seriesTripReq, seriesTrip);
            seriesTrip.setCreateId(userId);
            seriesTrip.setGmtCreate(LocalDateTime.now());
            seriesTrip.setId(id);
            seriesTrip.setCurrentStep(1);
            //负责人
            seriesTrip.setChargePersonId(seriesTripTeamRuleReq.getChargePersonId());
            seriesTrip.setChargePersonName(seriesTripTeamRuleReq.getChargePersonName());
            seriesTrip.setChargePersonNumber(seriesTripTeamRuleReq.getChargePersonNumber());
            //操作人

            seriesTrip.setOpId(seriesTripTeamRuleReq.getOpId());
            seriesTrip.setOpName(seriesTripTeamRuleReq.getOpName());
            seriesTrip.setOpNumber(seriesTripTeamRuleReq.getOpNumber());
            seriesTripMapper.updateById(seriesTrip);
            seriesTripVisaMapper.delete(new QueryWrapper<SeriesTripVisa>().lambda().eq(SeriesTripVisa::getTripId,id));
            List<TripVisaReq> visaReqList = seriesTripReq.getTripVisaList();
            if (CollectionUtils.isNotEmpty(visaReqList)) {
                List<SeriesTripVisa> seriesTripVisaList = new ArrayList<>();
                for (TripVisaReq tripVisaReq : visaReqList) {
                    SeriesTripVisa seriesTripVisa = newCreateEntityUserId(SeriesTripVisa.class, null, userId);
//                    seriesTripVisa.setId(tripVisaReq.getVisaId());
                    seriesTripVisa.setVisaId(tripVisaReq.getVisaId());
                    seriesTripVisa.setId(IdWorker.getId());
                    seriesTripVisa.setName(tripVisaReq.getName());
                    seriesTripVisa.setTripId(id);
                    seriesTripVisaList.add(seriesTripVisa);
                }
                seriesTripVisaMapper.insertBatchSomeColumn(seriesTripVisaList);
            }
            seriesTripInsuranceMapper.delete(new QueryWrapper<SeriesTripInsurance>().lambda().eq(SeriesTripInsurance::getTripId,id));
            List<TripInsuranceReq> insuranceReqList =seriesTripReq.getInsuranceList();
            if (CollectionUtils.isNotEmpty(insuranceReqList)){
                List<SeriesTripInsurance> seriesTripInsuranceList =new ArrayList<>();
                for (TripInsuranceReq tripInsuranceReq : insuranceReqList) {
                    SeriesTripInsurance seriesTripInsurance = newCreateEntityUserId(SeriesTripInsurance.class, null, userId);
                    seriesTripInsurance.setName(tripInsuranceReq.getName());
                    seriesTripInsurance.setTripId(id);
                    seriesTripInsurance.setId(IdWorker.getId());
                    seriesTripInsurance.setInsuranceId(tripInsuranceReq.getInsuranceId());
                    seriesTripInsuranceList.add(seriesTripInsurance);
                }
                seriesTripInsuranceMapper.insertBatchSomeColumn(seriesTripInsuranceList);
            }


            //新修改团队规则数据
            SeriesTripTeamRule seriesTripTeamRule = new SeriesTripTeamRule();
            BeanUtils.copyProperties(seriesTripTeamRuleReq, seriesTripTeamRule);

            Long ruleId = seriesTripTeamRule.getId();
            List<Passenger> passengerList = seriesTripTeamRuleReq.getPassenger();
            if (CollectionUtils.isNotEmpty(passengerList)) {
//                seriesTripTouristTypeService.remove(new QueryWrapper<SeriesTripTouristType>().lambda().eq(SeriesTripTouristType::getTripId,id));
                List<SeriesTripTouristType> tripTouristTypeList = new ArrayList();
                SeriesTripTouristType seriesTripTouristType = null;
                for (Passenger passenger : passengerList) {
                    seriesTripTouristType = newUpdateEntityUserId(SeriesTripTouristType.class, null, userId);
//                    seriesTripTouristType.setId(IdWorker.getId());
                    seriesTripTouristType.setId(passenger.getId());
                    seriesTripTouristType.setTripId(id);
                    seriesTripTouristType.setRuleId(ruleId);
                    seriesTripTouristType.setMainDataId(passenger.getMainDataId());
                    seriesTripTouristType.setAgeBegin(passenger.getAgeBegin());
                    seriesTripTouristType.setAgeEnd(passenger.getAgeEnd());
                    seriesTripTouristType.setName(passenger.getName());
                    seriesTripTouristType.setSort(passenger.getSort());
                    seriesTripTouristType.setIsOccupyBed(passenger.getIsOccupyBed());
                    tripTouristTypeList.add(seriesTripTouristType);
                }
                seriesTripTouristTypeService.updateBatchById(tripTouristTypeList);
            }
            baseMapper.updateById(seriesTripTeamRule);

            seriesTripInfoChangeRuleService.remove(new QueryWrapper<SeriesTripInfoChangeRule>().lambda().eq(SeriesTripInfoChangeRule::getTripId, id));

            List<SeriesTripInfoChangeRuleReq> ruleList = seriesTripTeamRuleReq.getChangeRuleList();
            if (CollectionUtils.isNotEmpty(ruleList)) {
                List<SeriesTripInfoChangeRule> seriesTripInfoChangeRuleList = new ArrayList<>();
                SeriesTripInfoChangeRule seriesTripInfoChangeRule = null;
                for (SeriesTripInfoChangeRuleReq seriesTripInfoChangeRuleReq : ruleList) {
                    seriesTripInfoChangeRule = newCreateEntityUserId(SeriesTripInfoChangeRule.class, null, userId);
                    seriesTripInfoChangeRule.setTripId(id);
                    seriesTripInfoChangeRule.setGroupRuleId(ruleId);
                    seriesTripInfoChangeRule.setCreateId(userId);
                    seriesTripInfoChangeRule.setGmtCreate(LocalDateTime.now());
                    seriesTripInfoChangeRule.setMainDataId(seriesTripInfoChangeRuleReq.getMainDataId());
                    seriesTripInfoChangeRule.setName(seriesTripInfoChangeRuleReq.getName());
                    seriesTripInfoChangeRuleList.add(seriesTripInfoChangeRule);
                }
                seriesTripInfoChangeRuleService.saveBatch(seriesTripInfoChangeRuleList);
            }
            tripIdDTO.setId(id);
        }
        //第一步，后面需要拿id进行关联

        // 更新缓存
        CompletableFuture.runAsync(() -> {
            iSeriesTripAppService.updateTripCache(new TripCacheUpdateReq().setIds(Arrays.asList(tripIdDTO.getId())));
        });
        return tripIdDTO;
    }

    private void changeMainData(){
        //新增基本资料
        //            //目的地主数据
//            MainDataReq destination = tripBasicInformationReq.getSeriesTripReq().getDestination();
//            seriesTrip.setDestinationId(destination.getLabel());
//            seriesTrip.setDestination(destination.getValue());
//            //出发地数据
//            MainDataReq departurePlace = tripBasicInformationReq.getSeriesTripReq().getDeparturePlace();
//            seriesTrip.setDeparturePlaceId(departurePlace.getLabel());
//            seriesTrip.setDeparturePlace(departurePlace.getValue());
//            //旅游组别主数据
//            MainDataReq tourType = tripBasicInformationReq.getSeriesTripReq().getTourType();
//            seriesTrip.setTourTypeId(tourType.getLabel());
//            seriesTrip.setTourTypeName(tourType.getValue());
//            //旅行团种类主数据
//            MainDataReq groupType = tripBasicInformationReq.getSeriesTripReq().getGroupType();
//            seriesTrip.setGroupTypeId(groupType.getLabel());
//            seriesTrip.setGroupTypeName(groupType.getValue());
//            //团队性质主数据
//            MainDataReq groupNature = tripBasicInformationReq.getSeriesTripReq().getGroupNature();
//            seriesTrip.setGroupNatureId(groupNature.getLabel());
//            seriesTrip.setGroupNatureName(groupNature.getValue());
//            //去程交通类型主数据
//            MainDataReq departureTrafficType = tripBasicInformationReq.getSeriesTripReq().getDepartureTrafficType();
//            seriesTrip.setDepartureTrafficTypeId(departureTrafficType.getLabel());
//            seriesTrip.setDepartureTrafficType(departureTrafficType.getValue());
//            //去程交通类型主数据
//            MainDataReq returnTrafficType = tripBasicInformationReq.getSeriesTripReq().getReturnTrafficType();
//            seriesTrip.setReturnTrafficTypeId(returnTrafficType.getLabel());
//            seriesTrip.setReturnTrafficType(returnTrafficType.getValue());
//            //负责人
//            ChargePersonReq chargePersonReq = seriesTripTeamRuleReq.getChargePerson();
//            seriesTrip.setChargePersonId(chargePersonReq.getLabel());
//            seriesTrip.setChargePersonName(chargePersonReq.getValue());
//            seriesTrip.setChargePersonNumber(chargePersonReq.getChargePersonNumber());
//            //操作人
//            ChargePersonReq op = seriesTripTeamRuleReq.getChargePerson();
//            seriesTrip.setOpId(op.getLabel());
//            seriesTrip.setOpName(op.getValue());
//            seriesTrip.setOpName(op.getChargePersonNumber());
        //新增团规则
//            //随团物品主数据
//            MainDataReq item = seriesTripTeamRuleReq.getItem();
//            seriesTripTeamRule.setItemId(item.getLabel());
//            seriesTripTeamRule.setItem(item.getValue());
//
//            //徽章颜色主数据
//            MainDataReq badgeColor = seriesTripTeamRuleReq.getBadgeColor();
//            seriesTripTeamRule.setBadgeColorId(badgeColor.getLabel());
//            seriesTripTeamRule.setBadgeColor(badgeColor.getValue());
//
//            //小费主数据
//            MainDataReq consumption = seriesTripTeamRuleReq.getConsumption();
//            seriesTripTeamRule.setConsumptionId(consumption.getLabel());
//            seriesTripTeamRule.setConsumptionName(consumption.getValue());
//
//            //退团扣费数据
//            MainDataReq deductionRules = seriesTripTeamRuleReq.getDeductionRules();
//            seriesTripTeamRule.setDeductionRulesId(deductionRules.getLabel());
//            seriesTripTeamRule.setDeductionRulesName(deductionRules.getValue());
//
//            //不成团数据
//            MainDataReq notGroupRules = seriesTripTeamRuleReq.getNotGroupRules();
//            seriesTripTeamRule.setNotGroupRulesId(notGroupRules.getLabel());
//            seriesTripTeamRule.setNotGroupRulesName(notGroupRules.getValue());
//
//            //住房类型
//            HousingReq housing = seriesTripTeamRuleReq.getHousing();
//            seriesTripTeamRule.setHousingTypeId(housing.getLabel());
//            seriesTripTeamRule.setHousingType(housing.getValue());
//            seriesTripTeamRule.setBedNum(housing.getBedNum());
//            seriesTripTeamRule.setOccupyBedNum(housing.getOccupyBedNum());
//            seriesTripTeamRule.setNotOccupyBedNum(housing.getNotOccupyBedNum());
    }
}
